react使用hooks启用setInterval中state值不变的问题 |
您所在的位置:网站首页 › react hooks 计时器 › react使用hooks启用setInterval中state值不变的问题 |
这里写使用自定义目录标题
使用useEffect在函数组件中启用定时器存在问题的修复方式可用的修复方式1可用的修复方式2
使用useEffect在函数组件中启用定时器
function UseReducerTemplate(props){
const [count, setCount] = useState(0);
useEffect(() => {
let id = setInterval(() => {
setCount(count + 1);
}, 1000);
return () => clearInterval(id);
}, []);
return {count};
};
由于需要启用定时器,而且防止变量刷新,需要将useEffect中的第二个参数设置为空数组,防止重复渲染生成计数器,以及清除计数器。此时在函数第一次render()的时候创建定时器。相当于class组件中的componentDidMount生命周期创建定时器。 存在问题:此时进行渲染后发现页面中当0变成1后页面保持不变,并且一直是1。 原因:当第二个参数为空时此时第一个函数中形成了闭包,此时count值成为了一个常量0,而读取不到外部count值的变化,此时第一个函数是一个独立函数,其内部的状态和外部无关 存在问题的修复方式 function UseReducerTemplate(props){ const [count, setCount] = useState(0); useEffect(() => { let id = setInterval(() => { setCount(count + 1); }, 1000); return () => clearInterval(id); }, [count]); return {count}; };如果此时函数想要正常读取外部的count则需要将useState中count值传入第二个参数,但是此时会出现刚开始提到的问题,计数器在重复的挂载清除,会存在比较大的性能损耗,因此此种方式也是不可取的 在hooks使用规范上有提示到,hooks内部使用的到状态参数要传入到第二个参数数组中,即effect 函数中引用的每个值也应出现在依赖项数组中。 可用的修复方式1 function UseReducerTemplate(props){ const [count, setCount] = useState(0); useEffect(() => { let id = setInterval(() => { setCount(count => count + 1); }, 1000); return () => clearInterval(id); }, []); return {count}; };由于setState()中还可以接受一个函数,setState(preState => { return newState }), 通过此种方式可以读取到上一次的state值,并在上一值的基础上进行更改, 函数返回方式在维护一个state对象时有较好的使用效果,例如:setUser((user) = > ({ …user, name: ‘Nathan’ })); 可用的修复方式2 function UseReducerTemplate(props){ const [count, setCount] = useState(0); const countRef = useRef(count); useEffect(() =>{ countRef.current = count; }); useEffect(() => { let id = setInterval(() => { setCount(countRef.current + 1); }, 1000); return () => clearInterval(id); }, []); return {count}; };由于此处产生了闭包,导致函数内部count成为了一个常量,因此我们创建一个count值的引用,此处countRef是维护一个对象,由于hooks在函数中是顺序调用,因此每次count值修改后其内部的curent会更改为当前的count值,因此我们在setInterval中可以正确进行读取 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |